home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / 1987 / 12 / naro / loadexe.c < prev    next >
Text File  |  1987-12-21  |  13KB  |  135 lines

  1. #include <stdio.h>                                                                           
  2. #include <io.h>                                                                              
  3. #include <stdlib.h>                                                                          
  4. #include <string.h>                                                                          
  5. #include <malloc.h>                                                                          
  6. #include <dos.h>                                                                             
  7.                                                                                              
  8. #include "loc.h"                                                                             
  9. #include "externs.h"                                                                         
  10.                                                                                              
  11.                                                                                              
  12. char  *warn_str = "Warning: Unable to locate virtual segment %04X\n" ;                       
  13.                                                                                              
  14. char  *load_exe_file()                                                                       
  15. {                                                                                            
  16.    char  buf[128] ;                                                                          
  17.    int   count, i ;                                                                          
  18.    long  seek_pos ;                                                                          
  19.    unsigned int   module_size, pseg, *reloc_ptr, segment ;                                   
  20.    unsigned int   read_size, mem_size ;                                                      
  21.    char  *load_addr, *entry, *str ;                                                          
  22.                                                                                              
  23.    EXE_HEADER  header;                                                                       
  24.    SEG_DESCRIPTOR *p ;                                                                       
  25.                                                                                              
  26.    /*                                                                                        
  27.       This function reads in the .EXE file and performs the fixup of any                     
  28.       segment references.                                                                    
  29.    */                                                                                        
  30.                                                                                              
  31.    /* Read in the .EXE file header information */                                            
  32.    count = read(exe_file, (char *) &header, sizeof(header)) ;                                
  33.    if (count != sizeof(header))   {                                                          
  34.       perror(__FILE__) ;                                                                     
  35.       exit(1) ;                                                                              
  36.    }                                                                                         
  37.                                                                                              
  38.    /* Exit if not a valid .EXE file */                                                       
  39.    if (header.signature != 0x5A4D)   {                                                       
  40.       perror("Not an .EXE file") ;                                                           
  41.       exit(1) ;                                                                              
  42.    }                                                                                         
  43.                                                                                              
  44.    /* Seek to the start of the load module */                                                
  45.    if (lseek(exe_file, (long) header.header_size * 16, SEEK_SET) == -1L) {                   
  46.       perror(__FILE__) ;                                                                     
  47.       exit(1) ;                                                                              
  48.    }                                                                                         
  49.                                                                                              
  50.    /* Compute how much memory can be allocated for reads */                                  
  51.    mem_size = 32 * 1024 ;                                                                    
  52.    if (mem_size > _memavl())                                                                 
  53.       mem_size = _memavl() ;                                                                 
  54.                                                                                              
  55.    /* Allocate the memory */                                                                 
  56.    if ((load_addr = malloc(mem_size)) == NULL)   {                                           
  57.       perror(__FILE__) ;                                                                     
  58.       exit(1) ;                                                                              
  59.    }                                                                                         
  60.                                                                                              
  61.    while (1)   {                                                                             
  62.       /* Read in a segment of the load module */                                             
  63.       read_size = read(exe_file, load_addr, mem_size) ;                                      
  64.       if (read_size == 0)   {                                                                
  65.          free(load_addr) ;                                                                   
  66.          break ;                                                                             
  67.       }                                                                                      
  68.                                                                                              
  69.       /* Write it back out to the temporary file */                                          
  70.       count = write(tmp_file, load_addr, read_size) ;                                        
  71.       if (count != read_size)   {                                                            
  72.          perror(__FILE__) ;                                                                  
  73.          exit(1) ;                                                                           
  74.       }                                                                                      
  75.    }                                                                                         
  76.                                                                                              
  77.    /* Find the relocation list */                                                            
  78.    if (lseek(exe_file, (long) header.first_reloc_item, SEEK_SET) == -1L) {                   
  79.       perror(__FILE__) ;                                                                     
  80.       exit(1) ;                                                                              
  81.    }                                                                                         
  82.                                                                                              
  83.    /* Perform the segment fixups on the temporary file */                                    
  84.    for (i = 0; i < header.reloc_items; i++)   {                                              
  85.       /* Read in a relocation item */                                                        
  86.       count = read(exe_file, (char *) &reloc_ptr, sizeof(reloc_ptr)) ;                       
  87.       if (count != sizeof(reloc_ptr))   {                                                    
  88.          perror(__FILE__) ;                                                                  
  89.          exit(1) ;                                                                           
  90.       }                                                                                      
  91.                                                                                              
  92.       /* Compute the position of the fixup in the temporary file */                          
  93.       seek_pos = (long) FP_SEG(reloc_ptr) ;                                                  
  94.       seek_pos = seek_pos * 16 + FP_OFF(reloc_ptr) ;                                         
  95.       if (lseek(tmp_file, seek_pos, SEEK_SET) == -1L)   {                                    
  96.          perror(__FILE__) ;                                                                  
  97.          exit(1) ;                                                                           
  98.       }                                                                                      
  99.                                                                                              
  100.       /* Read in the virtual segment from the fixup */                                       
  101.       count = read(tmp_file, (char *) &segment, sizeof(segment)) ;                           
  102.       if (count != sizeof(segment))   {                                                      
  103.          perror(__FILE__) ;                                                                  
  104.          exit(1) ;                                                                           
  105.       }                                                                                      
  106.                                                                                              
  107.       /* Perform the location */                                                             
  108.       if (locate_virtual_segment(segment, &pseg) == ERROR)                                   
  109.          fprintf(stderr, warn_str, segment) ;                                                
  110.                                                                                              
  111.       segment = pseg ;                                                                       
  112.                                                                                              
  113.       /* Re-seek back to the fixup */                                                        
  114.       if (lseek(tmp_file, seek_pos, SEEK_SET) == -1L)   {                                    
  115.          perror(__FILE__)  ;                                                                 
  116.          exit(1) ;                                                                           
  117.       }                                                                                      
  118.                                                                                              
  119.       /* Write the physical segment number to the fixup */                                   
  120.       count = write(tmp_file, (char *) &segment, sizeof(segment)) ;                          
  121.       if (count != sizeof(segment))   {                                                      
  122.          perror(__FILE__) ;                                                                  
  123.          exit(1) ;                                                                           
  124.       }                                                                                      
  125.    }                                                                                         
  126.                                                                                              
  127.    /* Process the program entry point */                                                     
  128.    if (locate_virtual_segment(header.code_seg_disp, &pseg) == ERROR)                         
  129.       fprintf(stderr, "Warning: Unable to locate entry point\n") ;                           
  130.                                                                                              
  131.    FP_SEG(entry) = pseg ;                                                                    
  132.    FP_OFF(entry) = header.initial_pc ;                                                       
  133.                                                                                              
  134.    return   entry ;                                                                          
  135. }